<script lang="ts" setup>
  import { ref, computed, onBeforeUnmount, shallowRef, reactive, watch } from 'vue';
  import { useRoute, useRouter } from 'vue-router';
  import '@wangeditor/editor/dist/css/style.css'; // 引入 css
  import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
  import {
    Button,
    Space,
    Popover,
    Form,
    FormItem,
    Select,
    Option,
    Message,
  } from '@arco-design/web-vue';
  import UserProfile from '/@/components/Connect/src/UserProfile.vue';
  import type { IToolbarConfig, IEditorConfig, IDomEditor } from '@wangeditor/editor';
  import type { IUploadConfigForImage } from '@wangeditor/upload-image-module/dist/upload-image-module/src/module/menu/config.d.ts';
  import {
    addDraft,
    publishArticle,
    updatePublishedDraft,
    updateDraft,
    queryArticleInfo,
  } from '/@/api/article';
  import type { ArticleRecord, AddArticleParams } from '/@/api/model/articleModel';
  import { queryArticleColumnList, queryArticleTagList } from '/@/api/recommend';
  import type { ArticleColumnRecord, ArticleTagRecord } from '/@/api/model/recommendModel';
  import { useDebounceFn } from '@vueuse/core';
  import { PageEnum } from '/@/enums/pageEnum';
  import { uploadImage } from '/@/api/common';
  import IconLogo from '/@/assets/home/logo.png';
  import { parseNumericArrayValue, stringifyArrayValue } from '/@/utils/helper';
  import { uuid } from '/@/utils/uuid';
  import { Upload } from '/@/components/Upload';
  import type { FileItem } from '/@/components/Upload';

  const route = useRoute();
  const router = useRouter();
  const fileList = ref<FileItem[]>([]);
  const isNew = computed(() => !draftId.value);
  const articleInfoRef = ref<ArticleRecord>();
  const isDraftSaving = ref(false);
  const draftsSaveStatusText = ref('文章将自动保存至草稿箱中');
  const isPublished = computed(() => {
    return articleInfoRef.value?.type === 1;
  });
  const confirmText = computed(() => {
    return isPublished.value ? '更新' : '发布';
  });
  const draftId = ref(
    parseInt(
      Array.isArray(route.params.draft_id) ? route.params.draft_id[0] : route.params.draft_id,
      10,
    ) || 0,
  );
  const titleRef = ref('');
  const contentRef = ref('');
  const articleColumnListRef = ref<ArticleColumnRecord[]>([]);
  const articleTagListRef = ref<ArticleTagRecord[]>([]);
  const popoverVisible = ref(false);
  const onCancel = () => {
    popoverVisible.value = false;
  };

  // 编辑器实例，必须用 shallowRef
  const editorRef = shallowRef<IDomEditor>();
  const toolbarConfig: Partial<IToolbarConfig> = {
    toolbarKeys: [
      'bold',
      'italic',
      'underline',
      'header1',
      'header2',
      'blockquote',
      'codeBlock',
      'code',
      'bulletedList',
      'numberedList',
      'insertLink',
      'uploadImage',
    ],
  };
  const uploadImageConfig: Partial<IUploadConfigForImage> = {
    // 自定义上传
    async customUpload(file: File, insertFn) {
      // file 即选中的文件
      // 自己实现上传，并得到图片 url alt href
      const result = await uploadImage({ file });
      const { url, alt, href } = result;

      // 最后插入图片
      insertFn(url, alt, href);
    },
  };
  const editorConfig: Partial<IEditorConfig> = {
    placeholder: '请输入内容...',
    MENU_CONF: {
      uploadImage: uploadImageConfig,
    },
  };
  const handleCreated = (editor: IDomEditor) => {
    editorRef.value = editor; // 记录 editor 实例，重要！
  };
  const editorModeRef = ref('default');
  type FormRecord = Pick<AddArticleParams, 'column_id' | 'cover'> & { tag_id: number[] };
  const form = reactive<FormRecord>({
    column_id: undefined!,
    tag_id: [],
    cover: '',
  });

  // 草稿自动更新
  const updatePost = async () => {
    isDraftSaving.value = true;
    try {
      // 没有草稿的时候，新增一个草稿
      if (isPublished.value) {
        await updatePublishedDraft({
          title: titleRef.value,
          content: contentRef.value,
          id: draftId.value,
        });
      } else if (draftId.value === 0) {
        if (titleRef.value && contentRef.value) {
          const result = await addDraft({
            title: titleRef.value,
            content: contentRef.value,
          });
          draftId.value = result.id;
          router.replace(`/editor/drafts/${draftId.value}`);
        }
      } else {
        await updateDraft({
          title: titleRef.value,
          content: contentRef.value,
          id: draftId.value,
        });
      }
    } finally {
      isDraftSaving.value = false;
    }
  };
  const updatePostDebounce = useDebounceFn(updatePost, 500);
  const watchUpdatePostDebounce = () => {
    watch(contentRef, () => {
      updatePostDebounce();
    });
  };

  // 栏目
  (async () => {
    const data = await queryArticleColumnList();
    articleColumnListRef.value = data;
  })();

  // 标签
  (async () => {
    const data = await queryArticleTagList();
    articleTagListRef.value = data;
  })();

  // 组件销毁时，也及时销毁编辑器
  onBeforeUnmount(() => {
    const editor = editorRef.value;
    if (editor == null) return;
    editor.destroy();
  });

  async function handleSubmit(data: any) {
    const values: FormRecord = data.values;
    const params = {
      id: draftId.value,
      title: titleRef.value,
      content: contentRef.value,
      tag_id: stringifyArrayValue(values.tag_id),
      column_id: values.column_id,
      cover: values.cover,
    };

    await publishArticle(params);
    Message.success('发布成功！');
    router.push(PageEnum.CREATOR_PUBLISHED);
  }

  watch(isDraftSaving, () => {
    draftsSaveStatusText.value = isDraftSaving.value ? '保存中...' : '保存成功';
  });

  // 读取文章
  (async () => {
    if (!isNew.value) {
      articleInfoRef.value = await queryArticleInfo({ id: draftId.value });
      titleRef.value = articleInfoRef.value.title;
      contentRef.value = articleInfoRef.value.content;
      form.column_id = articleInfoRef.value.column_id;
      form.tag_id = parseNumericArrayValue(articleInfoRef.value.tag_id);
      form.cover = articleInfoRef.value.cover;
      if (form.cover) {
        const uid = uuid();
        fileList.value = [
          {
            uid,
            name: form.cover,
            url: form.cover,
          },
        ];
      }
    }
    watchUpdatePostDebounce();
  })();

  watch(fileList, (fileList) => {
    const url = fileList?.[0]?.response?.url;
    if (url) {
      form.cover = url;
    }
  });

  console.log('不要吹灭你的灵感和你的想象力; 不要成为你的模型的奴隶。 ——文森特・梵高');
</script>

<template>
  <div class="bg-white">
    <div class="relative">
      <header class="h-[80px] z-10">
        <div class="flex items-center h-full max-w-1440 w-full ml-auto mr-auto">
          <a class="flex-none ml-[71px] mr-[48px] text-4xl text-black font-bold" href="/">
            <img class="w-[130px]" :src="IconLogo" />
          </a>
          <nav class="h-full flex-auto">
            <ul class="flex flex-row-reverse h-full items-center justify-between">
              <ul class="flex items-center justify-end">
                <Space>
                  <div class="text-gray-300">{{ draftsSaveStatusText }}</div>
                  <Button href="/creator/content/article/drafts" target="_blank">草稿箱</Button>
                  <Popover
                    trigger="click"
                    v-model:popupVisible="popoverVisible"
                    position="br"
                    contentClass="w-[345px] p-0"
                  >
                    <Button type="primary">{{ confirmText }}</Button>
                    <template #content>
                      <Form :model="form" @submit="handleSubmit">
                        <div class="text-[20px] text-blank px-[33px] py-[11px]"
                          >{{ confirmText }}文章</div
                        >
                        <div class="border-t-[1px] border-b-[1px] border-gray px-[33px] py-[11px]">
                          <FormItem field="column_id" label="栏目" label-col-flex="60px" required>
                            <Select v-model="form.column_id">
                              <Option
                                v-for="item in articleColumnListRef"
                                :key="item.id"
                                :value="item.id"
                                >{{ item.name }}</Option
                              >
                            </Select>
                          </FormItem>
                          <FormItem field="tag_id" label="标签" label-col-flex="60px" required>
                            <Select v-model="form.tag_id" multiple :limit="3">
                              <Option
                                v-for="item in articleTagListRef"
                                :key="item.id"
                                :value="item.id"
                                >{{ item.name }}</Option
                              >
                            </Select>
                          </FormItem>
                          <FormItem label="文章封面" label-col-flex="60px">
                            <Upload v-model:file-list="fileList" />
                          </FormItem>
                        </div>
                        <div class="py-[11px] flex justify-end items-center px-[33px]">
                          <Space
                            ><Button @click="onCancel">取消</Button
                            ><Button type="primary" html-type="submit"
                              >确认并{{ confirmText }}</Button
                            ></Space
                          >
                        </div>
                      </Form>
                    </template>
                  </Popover>
                </Space>
                <li class="ml-[24px] mr-[65px] px-[12px]">
                  <UserProfile :isWhiteBg="true" />
                </li>
              </ul>
            </ul>
          </nav>
        </div>
      </header>
    </div>
    <div class="h-[41px] border-b-[1px] border-gray">
      <div class="max-w-[668px] mx-auto">
        <Toolbar :editor="editorRef" :defaultConfig="toolbarConfig" :mode="editorModeRef" />
      </div>
    </div>
    <div class="max-w-[668px] mx-auto h-[calc(100vh-121px)] overflow-y-auto">
      <input
        class="w-full bg-white border-0 pt-[3.333rem] text-[2.667rem] text-black font-bold outline-none"
        v-model="titleRef"
        placeholder="请输入标题"
        maxlength="80"
      />
      <Editor
        class="pt-[1.5rem]"
        :style="{ height: 'auto' }"
        v-model="contentRef"
        :defaultConfig="editorConfig"
        :mode="editorModeRef"
        @on-created="handleCreated"
      />
    </div>
  </div>
</template>
